/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package aspect.example;
import static aspect.core.AspectLauncher.*;
import static aspect.core.AspectRenderer.*;
import aspect.entity.Entity;
import aspect.entity.behavior.Behavior;
import aspect.entity.behavior.PlayerControl;
import aspect.event.KeyEvent;
import aspect.event.MouseEvent;
import aspect.physics.RigidBody;
import aspect.physics.Time;
import aspect.render.Material;
import aspect.render.Mesh;
import aspect.render.ViewModel;
import aspect.render.shader.ShaderProgram;
import static aspect.resources.Resources.loadObjModel;
import static aspect.resources.Resources.rect;
import aspect.util.Angles;
import aspect.util.Color;
import aspect.util.Matrix4x4;
import aspect.util.Transform;
import aspect.util.Trig;
import aspect.util.Vector2;
import aspect.util.Vector3;
import aspect.world.World;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import static org.lwjgl.input.Keyboard.*;
import static org.lwjgl.input.Mouse.*;
/**
*
* @author MillerV
*/
public class Frigate extends Entity {
float thrust = 0.0f;
private final Entity engineRF;
private final Entity engineRR;
private final Entity engineLF;
private final Entity engineLR;
private final RigidBody rigidBody;
private float mouseSensitivity = 0.01f;
public Transform view;
private final Behavior[] controls;
private int control = 0;
public Frigate() {
super(loadObjModel("frigate", new File("models/frigate_body.obj"), new Vector3(10.0f)));
rigidBody = new RigidBody();
rigidBody.mass = 10.0f;
rigidBody.setUniformMOI(100);
addBehavior(rigidBody);
ViewModel engineRight = loadObjModel("rengine", new File("models/thruster_medium.obj"), new Vector3(10.0f));
ViewModel engineLeft = loadObjModel("lengine", new File("models/thruster_medium.obj"), new Vector3(-10.0f, 10.0f, 10.0f));
engineRF = new Entity(engineRight);
engineRR = new Entity(engineRight);
engineLF = new Entity(engineLeft);
engineLR = new Entity(engineLeft);
engineLF.transform.scale.x = -1.0f;
engineLR.transform.scale.x = -1.0f;
engineRR.transform.position = new Vector3(8.1f, 0.5f, 6.7f);
engineRF.transform.position = new Vector3(10.1f, -0.5f, -6.7f);
engineLR.transform.position = new Vector3(-8.1f, 0.5f, 6.7f);
engineLF.transform.position = new Vector3(-10.1f, -0.5f, -6.7f);
addChild(engineLR);
addChild(engineLF);
addChild(engineRF);
addChild(engineRR);
ViewModel turret = loadObjModel("turret", new File("models/turret.obj"), new Vector3(10.0f));
Entity turret1 = new Entity(turret);
Entity turret2 = new Entity(turret);
Entity turret3 = new Entity(turret);
Entity turret4 = new Entity(turret);
Entity turret5 = new Entity(turret);
Entity turret6 = new Entity(turret);
turret1.transform.position = new Vector3(1.25f, 1.2f, 9.0f);
turret2.transform.position = new Vector3(-1.25f, 1.2f, 9.0f);
turret3.transform.position = new Vector3(1.25f, 1.2f, -2.5f);
turret4.transform.position = new Vector3(-1.25f, 1.2f, -2.5f);
turret5.transform.position = new Vector3(3.25f, 0.2f, -5.5f);
turret6.transform.position = new Vector3(-3.25f, 0.2f, -5.5f);
addChild(turret1);
addChild(turret2);
addChild(turret3);
addChild(turret4);
addChild(turret5);
addChild(turret6);
engineLR.addBehavior(new Exhaust());
engineLF.addBehavior(new Exhaust());
engineRR.addBehavior(new Exhaust());
engineRF.addBehavior(new Exhaust());
controls = new Behavior[7];
controls[0] = new EngineControl();
controls[1] = new TurretControl(turret1);
controls[2] = new TurretControl(turret2);
controls[3] = new TurretControl(turret3);
controls[4] = new TurretControl(turret4);
controls[5] = new TurretControl(turret5);
controls[6] = new TurretControl(turret6);
addBehavior(new Behavior() {
@Override
public void update() {
controls[control].ent = Frigate.this;
controls[control].update();
}
@Override
public void render() {
controls[control].ent = Frigate.this;
controls[control].render();
}
});
view = new Transform();
}
private class Exhaust extends Behavior {
@Override
public void update() {
if (thrust > 0) {
Matrix4x4 m = ent.transform.global.getMdlMatrix();
Vector3 point = m.transformPoint(new Vector3(1.0f, 0.0f, 3.0f));
Vector3 vel = Frigate.this.rigidBody().velocity;
vel = vel.plus(Vector3.cross(Frigate.this.rigidBody().angularVelocity, point.minus(ent.transform.global.position)));
World.main.add(new Trail(point, vel.plus(ent.transform.global.forward().times(-20.0f)), Frigate.this));
}
}
}
private class TurretControl extends Behavior {
private final Angles angles;
private final ViewModel beam;
private final Entity turret;
private final Behavior shooty;
public TurretControl(final Entity turret) {
this.turret = turret;
this.angles = Angles.zero();
Material m = new Material(Color.BLACK);
m.emissive = Color.ORANGE;
beam = rect(m, 100, 0.05f);
beam.transform.forward = Vector3.xAxis();
beam.transform.up = Vector3.yAxis();
beam.transform.position = new Vector3(0.15f, 0.075f, -50.5f);
beam.transform.position = new Vector3(0.15f, 0.075f, -50.5f);
//turret.addChild(new Entity(beam));
shooty = new Behavior() {
@Override
public void update() {
HashMap<Color, Entity> key = new HashMap<>();
if (isButtonDown(0)) {
ShaderProgram.lock(ShaderProgram.COLOR);
for (Entity entity : World.main) {
Color c = Color.random();
key.put(c, entity);
ShaderProgram.COLOR.setVar("color", c);
entity.render();
}
ShaderProgram.unlock();
Color c = getPixelColor(new Vector2(getCanvasWidth() / 2, getCanvasHeight() / 2));
Entity hit = key.get(c);
if (hit instanceof Fighter) {
Fighter f = (Fighter) hit;
if (f.health > 0) {
f.health -= 200 * Time.deltaTime();
if (f.health <= 0) {
f.die();
}
}
}
}
}
@Override
public void render() {
if (isButtonDown(0)) {
beam.transform.position.x *= -1;
beam.transform.global = turret.transform.global.concat(beam.transform);
beam.render();
beam.transform.position.x *= -1;
beam.transform.global = turret.transform.global.concat(beam.transform);
beam.render();
}
}
};
}
@Override
public void update() {
Transform transform = new Transform();
float x = PlayerControl.getMouseDX() * 0.02f;
float y = PlayerControl.getMouseDY() * 0.02f;
PlayerControl.centerMouse();
angles.pitch += y;
angles.yaw += x;
angles.pitch = Math.max(angles.pitch, 0);
angles.pitch = Math.min(angles.pitch, Trig.EIGHTH_CIRCLE);
transform.position = turret.transform.position;
transform.setEulerAngles(angles);
//transform.up = m.transformVector(transform.up);
turret.transform.forward = turret.transform.forward.rotateTowards(transform.forward, 4 * Time.deltaTime());
turret.transform.up = Vector3.yAxis();
Transform t = Frigate.this.transform.concat(transform);
t.position = t.position.plus(t.forward().times(0.3f));
t.position = t.position.plus(t.up().times(0.15f));
view.set(t);
shooty.update();
}
@Override
public void render() {
shooty.render();
}
}
private class EngineControl extends Behavior {
private final Transform internalView = new Transform();
public EngineControl() {
addKeyListener(this);
}
@Override
public void keyEvent(KeyEvent evt) {
if (evt.type) {
if (evt.key == KEY_Q) {
control--;
if (control < 0) {
control = controls.length - 1;
}
} else if (evt.key == KEY_E) {
control++;
if (control >= controls.length) {
control = 0;
}
}
}
}
@Override
public void update() {
float y = PlayerControl.getMouseDY() * mouseSensitivity;
float x = -PlayerControl.getMouseDX() * mouseSensitivity;
PlayerControl.centerMouse();
Matrix4x4 m = Matrix4x4.identity();
m = m.rotateY(x);
m = m.rotate(internalView.right(), y);
internalView.forward = m.transformVector(internalView.forward);
Matrix4x4 m2 = transform.getMdlMatrix();
view.up = m2.transformVector(internalView.up);
view.setForward(m2.transformVector(internalView.forward));
view.position = transform.position.plus(view.forward.times(-20.0f));
Vector3 engineDir1 = new Vector3(0, internalView.forward.y, internalView.forward.z);
Vector3 engineDir2 = new Vector3(0, -internalView.forward.y, internalView.forward.z);
Vector3 rfDir = engineDir1;
Vector3 rrDir = engineDir1;
Vector3 lfDir = engineDir1;
Vector3 lrDir = engineDir1;
if (isKeyDown(KEY_W)) {
rrDir = Vector3.zAxis().negate();
lrDir = Vector3.zAxis().negate();
thrust = 1.0f;
} else if (isKeyDown(KEY_S)) {
rfDir = Vector3.zAxis().negate();
lfDir = Vector3.zAxis().negate();
thrust = 1.0f;
} else if (isKeyDown(KEY_D)) {
thrust = 1.0f;
lfDir = engineDir2;
lrDir = engineDir2;
} else if (isKeyDown(KEY_A)) {
thrust = 1.0f;
rfDir = engineDir2;
rrDir = engineDir2;
} else if (isKeyDown(KEY_LSHIFT)) {
rfDir = Vector3.zAxis().negate();
rrDir = Vector3.zAxis().negate();
lfDir = Vector3.zAxis().negate();
lrDir = Vector3.zAxis().negate();
thrust = 1.0f;
} else if (isKeyDown(KEY_LCONTROL)) {
rfDir = Vector3.zAxis();
rrDir = Vector3.zAxis();
lfDir = Vector3.zAxis();
lrDir = Vector3.zAxis();
thrust = 1.0f;
} else {
thrust = 0;
}
engineRF.transform.setForward(engineRF.transform.forward.rotateTowards(rfDir, 4 * Time.deltaTime()));
engineRR.transform.setForward(engineRR.transform.forward.rotateTowards(rrDir, 4 * Time.deltaTime()));
engineLF.transform.setForward(engineLF.transform.forward.rotateTowards(lfDir, 4 * Time.deltaTime()));
engineLR.transform.setForward(engineLR.transform.forward.rotateTowards(lrDir, 4 * Time.deltaTime()));
float rfThrust = thrust;
float rrThrust = thrust;
float lfThrust = thrust;
float lrThrust = thrust;
engineRF.transform.global = transform.concat(engineRF.transform);
engineRR.transform.global = transform.concat(engineRR.transform);
engineLF.transform.global = transform.concat(engineLF.transform);
engineLR.transform.global = transform.concat(engineLR.transform);
rigidBody.impel(engineRF.transform.global.forward.times(rfThrust * Time.deltaTime()), engineRF.transform.global.position.minus(ent.transform.position));
rigidBody.impel(engineRR.transform.global.forward.times(rrThrust * Time.deltaTime()), engineRR.transform.global.position.minus(ent.transform.position));
rigidBody.impel(engineLF.transform.global.forward.times(lfThrust * Time.deltaTime()), engineLF.transform.global.position.minus(ent.transform.position));
rigidBody.impel(engineLR.transform.global.forward.times(lrThrust * Time.deltaTime()), engineLR.transform.global.position.minus(ent.transform.position));
}
}
}